package com.wss.lsl.test.driven.common.util;

/**
 * 一维向量工具
 * 
 * @author sean
 *
 */
public class OneDimensionalVectorUtil {

	/**
	 * 循环移动向量
	 * 
	 * @param chars
	 * @param i
	 * @return
	 */
	public static char[] loopMove(char[] chars, int i) {

		final int length = chars.length;
		if (i <= 0 || i >= length) {
			throw new IllegalArgumentException(
					"i must be more than zero and less than chars.length");
		}

		int subIndex = 0;
		char t = chars[subIndex];
		int count = 0;
		int index = 0;
		do {
			if (((++index) * i + subIndex) % length == subIndex) {// 先检查后一个元素的位置
				chars[((index - 1) * i + subIndex) % length] = t;// 上一个元素取t
				count++;
				index = 0;
				subIndex++;
				t = chars[subIndex];// t取下一个元素
			} else {
				chars[((index - 1) * i + subIndex) % length] = chars[(index * i + subIndex)
						% length];
				count++;
			}
		} while (count < length);

		return chars;
	}

	/**
	 * 反转法移动一维向量
	 * 
	 * @param chars
	 * @param i
	 * @return
	 */
	public static char[] reversalMove(char[] chars, final int i) {
		final int length = chars.length;
		if (i <= 0 || i >= length) {
			throw new IllegalArgumentException(
					"i must be more than zero and less than chars.length");
		}

		reversalArray(chars, 0, i);
		reversalArray(chars, i, length);
		reversalArray(chars, 0, length);

		return chars;
	}

	private static char[] reversalArray(char[] array, int begin, int end) {

		char t;
		for (int i = begin, j = end - 1; i < j; i++, j--) {
			t = array[i];
			array[i] = array[j];
			array[j] = t;
		}
		return array;
	}

	/**
	 * 递归移动向量
	 * 
	 * @param chars
	 * @param i
	 * @return
	 */
	public static char[] recursionMove(char[] chars, final int left, int n) {
		final int length = chars.length;
		if (left <= 0 || left >= length) {
			throw new IllegalArgumentException(
					"left must be more than zero and less than chars.length");
		}

		final int right = n - left;
		int count, begin, newLeft;
		if (left > right) {
			count = right;
			begin = left - right;
			newLeft = begin;
		} else {
			count = left;
			begin = 0;
			newLeft = left;
		}
		int end = begin + count;
		for (int i = begin; i < end; i++) {
			char t = chars[i];
			chars[i] = chars[i + right];
			chars[i + right] = t;
		}
		if (left == right) {
			return chars;
		}
		n = n - count;
		return recursionMove(chars, newLeft, n);
	}
}
